home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / os2tools / bnklysrc / mailsubs.c < prev    next >
Text File  |  1989-07-08  |  29KB  |  1,213 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                            */
  3. /*                                                                            */
  4. /*        ------------         Bit-Bucket Software <no-Inc>                    */
  5. /*        \ 10001101 /         Writers and Distributors of                    */
  6. /*         \ 011110 /          No-Cost<no-tm> Software.                        */
  7. /*          \ 1011 /                                                            */
  8. /*           ------                                                            */
  9. /*                                                                            */
  10. /*    Copyright (C) 1987, 1988, 1989 by Robert Hartman and Vincent Perriello    */
  11. /*                                                                            */
  12. /*                                                                            */
  13. /*                   This module was written by Bob Hartman                    */
  14. /*                                                                            */
  15. /*                                                                            */
  16. /*                     BinkleyTerm Mail Control Routines                        */
  17. /*                                                                            */
  18. /*                                                                            */
  19. /*                                                                            */
  20. /*      For complete    details  of the licensing restrictions, please refer    */
  21. /*      to the License  agreement,  which  is published in its entirety in    */
  22. /*      the MAKEFILE and BT.C, and also contained in the file LICENSE.210.    */
  23. /*                                                                            */
  24. /*      USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  25. /*      BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  26. /*      THIS    AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,    OR IF YOU DO    */
  27. /*      NOT HAVE THESE FILES,  YOU SHOULD  IMMEDIATELY CONTACT THE AUTHORS    */
  28. /*      AT THE  ADDRESSES LISTED BELOW.  IN NO EVENT SHOULD YOU PROCEED TO    */
  29. /*      USE    THIS  FILE    WITHOUT  HAVING   ACCEPTED    THE  TERMS    OF     THE    */
  30. /*      BINKLEYTERM  LICENSING AGREEMENT,  OR SUCH OTHER    AGREEMENT AS YOU    */
  31. /*      ARE ABLE TO REACH WITH THE AUTHORS.                                    */
  32. /*                                                                            */
  33. /*                                                                            */
  34. /*      The Authors can be reached at the following addresses:                */
  35. /*                                                                            */
  36. /*      Robert C. Hartman                      Vincent E. Perriello            */
  37. /*      Spark Software                         VEP Software                    */
  38. /*      427-3 Amherst Street                     111 Carroll Street             */
  39. /*      CS2032, Suite 232                      Naugatuck, CT 06770            */
  40. /*      Nashua, NH 03061                                                        */
  41. /*                                                                            */
  42. /*      FidoNet 1:132/101                      FidoNet 1:141/491                */
  43. /*      Data      (603) 888-8179                 Data     (203) 729-7569         */
  44. /*                                                                            */
  45. /*      Please feel free to contact us at any time to share your comments     */
  46. /*      about our software and/or licensing policies.                         */
  47. /*                                                                            */
  48. /*--------------------------------------------------------------------------*/
  49.  
  50. #include <stdio.h>
  51. #include <signal.h>
  52. #include <ctype.h>
  53. #include <conio.h>
  54. #include <sys/types.h>
  55. #include <sys/stat.h>
  56. #include <string.h>
  57. #include <fcntl.h>
  58. #include <time.h>
  59. #include <process.h>
  60. #include <stdlib.h>
  61. #include <io.h>
  62.  
  63. #include "com.h"
  64. #include "xfer.h"
  65. #include "zmodem.h"
  66. #include "keybd.h"
  67. #include "sbuf.h"
  68. #include "sched.h"
  69. #include "externs.h"
  70. #include "prototyp.h"
  71. #include "vfossil.h"
  72. #include "find.h"   /*PLF Fri  05-05-1989  23:47:35 */
  73.  
  74. static char *estring (int);
  75. static char mail_stat (MAILP);
  76. static int xmit_install (MAILP, int, char *);    /*PLF Sat  05-06-1989  01:24:26 */
  77. static void xmit_sort (void);
  78.  
  79. /*PLF. I'm not sure if str_dh actually needs to have global scope for this
  80.  * module --- but since I can't make any sence of the program flow I am
  81.  * giving it global scope so there is no danger of me buggering
  82.  * up any logic.
  83.  *
  84.  * I was able to isolate the reference to dta_str in xmit_install because
  85.  * that function was static to this module. I can't say the same for
  86.  * xmit_delete() and xmit_reset() -- so which ever of these gets called
  87.  * first will allocate str_dh, WHICH WILL NEVER GET DEALLOCATED. It's not
  88.  * much..less than 100 bytes...still...I don't like it. If someone who
  89.  * is more intimate with this code could clean this up I would feel
  90.  * better.
  91.  *
  92.  * Global variables will be the death of you! Stop it!!
  93.  */
  94. static FSCAN *str_dh = NULL;
  95.  
  96. void boss_mail (manual_mode)
  97. int manual_mode;
  98. {
  99.    if (!net_params)
  100.       {
  101.       status_line ("!Insufficient data for session");
  102.       set_xy ("");
  103.       }
  104.    else
  105.       {
  106.       XON_DISABLE ();
  107.       if (!CARRIER)
  108.          {
  109.          mdm_init (modem_init);                  /* Reinitialize the modem    */
  110.          }
  111.  
  112.       do_mail (alias[0].Zone, boss_net, boss_node, manual_mode);
  113.       }
  114. }
  115.  
  116. int do_mail (bzone, bnet, bnode, manual)
  117. int bzone;
  118. int bnet;
  119. int bnode;
  120. int manual;
  121. {
  122.    long t, timerset ();
  123.  
  124.    caller = 1;
  125.    got_packet = 0;
  126.    got_arcmail = 0;
  127.    got_mail = 0;
  128.    sent_mail = 0;
  129.    no_WaZOO_Session = 0;
  130.    sprintf (junk, "%d:%d/%d", bzone, bnet, bnode);
  131.    remote_zone = bzone;
  132.    remote_net = bnet;
  133.    remote_node = bnode;
  134.    called_zone = bzone;
  135.    called_net = bnet;
  136.    called_node = bnode;
  137.    if ((!net_params) || (!nodeproc (junk)))
  138.       return (0);
  139.  
  140.    if (manual && CARRIER)                         /* called manually maybe? */
  141.       goto process_the_damned_mail;              /* yup, just do some mail */
  142.  
  143.    if (manual)
  144.       try_2_connect (newnodedes.PhoneNumber);     /* try to connect           */
  145.    else
  146.       {
  147.       /* If this is supposed to be only local, then get out if it isn't */
  148.       if (e_ptrs[cur_event]->behavior & MAT_LOCAL)
  149.          {
  150.          if (e_ptrs[cur_event]->node_cost < 0)
  151.             {
  152.             if (newnodedes.RealCost < -e_ptrs[cur_event]->node_cost)
  153.                {
  154.                return (0);
  155.                }
  156.             }
  157.          else
  158.             {
  159.             if (newnodedes.RealCost > e_ptrs[cur_event]->node_cost)
  160.                {
  161.                return (0);
  162.                }
  163.             }
  164.          }
  165.       /* If it is supposed to be 24 hour mail only, get out if it isn't */
  166.       if (newnodelist && (!(e_ptrs[cur_event]->behavior & MAT_NOMAIL24))
  167.           && (!(newnodedes.NodeFlags & B_CM)))
  168.          return (0);
  169.       /* If we aren't supposed to send to CM's now, get out */
  170.       if (newnodelist && (e_ptrs[cur_event]->behavior & MAT_NOCM)
  171.           && (newnodedes.NodeFlags & B_CM))
  172.          return (0);
  173.       /* Try to connect */
  174.       if (try_1_connect (newnodedes.PhoneNumber) == -1)
  175.          return (-1);
  176.       }
  177.  
  178. process_the_damned_mail:
  179.  
  180.    if (CARRIER)                                  /* if we did,               */
  181.       {
  182.       /* Clear out all the crap in case we had MNP stuff */
  183.       t = timerset (100);
  184.       while (!timeup (t))
  185.          time_release ();
  186.       CLEAR_OUTBOUND ();
  187.       CLEAR_INBOUND ();
  188.  
  189.       b_session (1);                             /* do a mail session       */
  190.  
  191.       mdm_hangup ();
  192.  
  193.       if (un_attended && fullscreen)
  194.          {
  195.          ++hist.connects;
  196.          sb_move (historywin, HIST_CONN_ROW, HIST_COL);
  197.          sprintf (junk, "%-4d", hist.connects);
  198.          sb_puts (historywin, junk);
  199.          }
  200.  
  201.       if (un_attended && (got_arcmail || got_packet || got_mail))
  202.          {
  203.          bad_call (bzone, bnet, bnode, -1);
  204.          receive_exit ();
  205.          }
  206.       return (1);
  207.       }
  208.    else
  209.       {
  210.       status_line ("+End of connection attempt");
  211.       }
  212.    return (2);
  213. }
  214.  
  215. int handle_inbound_mail ()
  216. {
  217.    long t, timerset ();                          /* used for the timeouts  */
  218.    int mr;                                         /* Modem response */
  219.  
  220.  
  221.    caller = 0;
  222.    remote_zone = 0;
  223.    remote_net = 0;
  224.    remote_node = 0;
  225.  
  226. inloop:
  227.  
  228.    if (!(server_mode && CARRIER) && !CHAR_AVAIL ())           /* Any action from modem? */
  229.       {
  230.       time_release ();
  231.       return (0);                                 /* No, nothing to do       */
  232.       }
  233.  
  234.    /* if outbound only, then return */
  235.    if ((cur_event >= 0) && (e_ptrs[cur_event]->behavior & MAT_OUTONLY))
  236.       {
  237.       time_release ();
  238.       return (0);
  239.       }
  240.  
  241.    mail_only = 1;
  242.    if ((cur_event >= 0) && (e_ptrs[cur_event]->behavior & MAT_BBS))
  243.       mail_only = 0;
  244.  
  245. should_answer:
  246.  
  247.    screen_blank = 0;
  248.    sb_show ();
  249.  
  250.    if (server_mode && CARRIER)
  251.       goto got_carrier;
  252.  
  253.    if ((mr = modem_response (100)) == 2)         /* see if we got a carrier */
  254.       {
  255.       t = timerset (200);                         /* 2 seconds...           */
  256.       while (!timeup (t))
  257.          time_release ();                         /* wait for other side    */
  258.       }
  259.    else if ((mr == 3) && (ans_str != NULL))      /* RING detected */
  260.       {
  261.       /*
  262.        * Try to make sure we don't send out the answer string while stuff is
  263.        * still coming from the modem.  Most modems don't like that kind of
  264.        * sequence (including HST's!).
  265.        */
  266.       t = timerset (100);
  267.       while (CHAR_AVAIL () && (!timeup (t)))
  268.          {
  269.          t = timerset (100);
  270.          MODEM_IN ();
  271.          }
  272.       CLEAR_INBOUND ();
  273.       mdm_cmd_string (ans_str, 0);                 /* transmit the answer
  274.                                                   * string */
  275.       goto should_answer;
  276.       }
  277.    else
  278.       {
  279.       t = timerset (6000);                         /* 1 minute               */
  280.       while ((!timeup (t))
  281.              && (!CHAR_AVAIL ())
  282.              && (!KEYPRESS ()))
  283.          time_release ();                         /* wait for another result */
  284.       if (KEYPRESS ())                             /* If aborted by user,    */
  285.          {
  286.          /* FOSSIL_CHAR();      *//* eat the character      */
  287.          return (1);                             /* and get out,           */
  288.          }
  289.       goto inloop;                                 /* else proceed along       */
  290.       }
  291.  
  292. got_carrier:
  293.  
  294.    if (CARRIER)                                  /* if we have a carrier,  */
  295.       {
  296.       /* Clear out all the crap in case we had MNP stuff */
  297.       t = timerset (100);
  298.       while (!timeup (t))
  299.          time_release ();
  300.       CLEAR_OUTBOUND ();
  301.       CLEAR_INBOUND ();
  302.  
  303.       b_session (0);                             /* do a mail session       */
  304.  
  305.       /* We got inbound mail */
  306.       if (got_arcmail || got_packet || got_mail)
  307.          {
  308.          receive_exit ();
  309.          }
  310.       }
  311.    mdm_hangup ();
  312.    return (1);
  313. }
  314.  
  315. void xmit_sameplace ()
  316. {
  317.    MAILP p, p1;
  318.  
  319.    /* Find the guy we just gave mail to */
  320.    p = find_mail (remote_zone, remote_net, remote_node);
  321.    remote_zone = remote_net = remote_node = 0;
  322.    if (p == NULL)
  323.       {
  324.       /* He is not there */
  325.       return;
  326.       }
  327.  
  328.    /* Save our current pointer */
  329.    p1 = next_mail;
  330.    if (p != next_mail)
  331.       {
  332.       /* If it is not the one we just gave mail to, save ptr and delete */
  333.       next_mail = p;
  334.       xmit_delete ();
  335.       next_mail = p1;
  336.       }
  337.    else
  338.       {
  339.       /* It was the guy at the head of the list, so just delete him */
  340.       xmit_delete ();
  341.       }
  342.  
  343.    /* If we came in with a null, leave with a null */
  344.    if (p1 == NULL)
  345.       next_mail = NULL;
  346.  
  347.    return;
  348. }
  349.  
  350. MAILP find_mail (zone, net, node)
  351. int zone;
  352. int net;
  353. int node;
  354. {
  355.    MAILP p;
  356.  
  357.    p = mail_top;
  358.    while (p != NULL)
  359.       {
  360.       if ((p->zone == zone) && (p->net == net) && (p->node == node))
  361.          break;
  362.       p = p->next;
  363.       }
  364.  
  365.    return (p);
  366. }
  367.  
  368. static int xmit_install (p, zone, fname)
  369. MAILP p;
  370. int zone;
  371. char *fname;    /*PLF Sat  05-06-1989  01:24:03 added fname parm */
  372. {
  373.    MAILP p1, p2;
  374.    int net, node, rettype;
  375. #ifdef IBMC
  376.    char tnet[5], tnode[5]; /*WRA added for IBM C/2 1.1 Bug */
  377.  
  378.    if (sscanf (fname, "%4s%4s.", tnet, tnode) != 2)
  379.       {
  380.       return (1);
  381.       }
  382.  
  383.    if (sscanf (tnet, "%04x", &net) + sscanf (tnode, "%04x", &node)  != 2)
  384.       {
  385.       return (1);
  386.       }
  387.  
  388. #else
  389.  
  390.    if (sscanf (fname, "%04x%04x.", &net, &node) != 2)
  391.       {
  392.       return (1);
  393.       }
  394.  
  395. #endif
  396.  
  397.    p2 = find_mail (zone, net, node);
  398.    if (p2 == NULL)
  399.       {
  400.       /* We didn't find it in what we have already */
  401.       p1 = p;
  402.       p1->net = net;
  403.       p1->node = node;
  404.       p1->zone = zone;
  405.       rettype = 0;
  406.       }
  407.    else
  408.       {
  409.       /* We found it, so we have to make sure the higher level routine knows */
  410.       p1 = p2;
  411.       rettype = 1;
  412.       }
  413.  
  414.    switch (fname[9])
  415.       {
  416.       case 'C':      /* Crash */
  417.          p1->mailtypes |= MAIL_CRASH;
  418.          break;
  419.  
  420.       case 'H':      /* Hold */
  421.          p1->mailtypes |= MAIL_HOLD;
  422.          break;
  423.  
  424.       case 'F':      /* Normal */
  425.       case 'O':
  426.          p1->mailtypes |= MAIL_NORMAL;
  427.          break;
  428.  
  429.       case 'D':      /* Direct */
  430.          p1->mailtypes |= MAIL_DIRECT;
  431.          break;
  432.  
  433.       case 'R':      /* Request */
  434.          p1->mailtypes |= MAIL_REQUEST;
  435.          break;
  436.       }
  437.  
  438.   if (!nodefind (p1->zone, p1->net, p1->node, 0))
  439.       {
  440.       p1->mailtypes |= MAIL_UNKNOWN;
  441.       return (rettype);
  442.       }
  443.  
  444.    /* If it is a held packet, we won't make a call */
  445.    if (fname[9] == 'H')
  446.       {
  447.       return (rettype);
  448.       }
  449. /*
  450.  * in mailsubs.c, near line 430, put this in:
  451.  * if( cur_event < 0 )
  452.  *           return(rettype);
  453.  *
  454.  * I have no idea what is supposed to happen here, but you can't reffer to
  455.  * e_ptrs[-1].xxx in os/2 (or in reality) when there ain't no e_ptr[-1]!!
  456.  */
  457. if(cur_event < 0)    /*PLF Mon  05-08-1989  11:19:18 */
  458.     return(rettype);
  459.  
  460.    /* If it is a crash only event and this wasn't crash, return */
  461.    if ((fname[9] != 'C') && (e_ptrs[cur_event]->behavior & MAT_CM))
  462.       {
  463.       return (rettype);
  464.       }
  465.  
  466.    /* If it is not supposed to be outbound requests, go on */
  467.    if ((e_ptrs[cur_event]->behavior & MAT_NOOUTREQ) &&
  468.        (fname[9] == 'R'))
  469.       {
  470.       return (rettype);
  471.       }
  472.  
  473.    /* Is this a local only event? */
  474.    if (e_ptrs[cur_event]->behavior & MAT_LOCAL)
  475.       {
  476.       /*
  477.        * If this is supposed to be only local, then get out if it isn't
  478.        */
  479.       if (e_ptrs[cur_event]->node_cost >= 0)
  480.          {
  481.          if (newnodedes.RealCost > e_ptrs[cur_event]->node_cost)
  482.             {
  483.             return (rettype);
  484.             }
  485.          }
  486.       else
  487.          {
  488.          if (newnodedes.RealCost < -e_ptrs[cur_event]->node_cost)
  489.             {
  490.             return (rettype);
  491.             }
  492.          }
  493.       }
  494.  
  495.    /* Is this a non-mail window event? */
  496.    if (newnodelist && (!(e_ptrs[cur_event]->behavior & MAT_NOMAIL24)))
  497.       {
  498.       /* If this guy can't handle crash, get out and try again */
  499.       if (!(newnodedes.NodeFlags & B_CM))
  500.          {
  501.          return (rettype);
  502.          }
  503.       }
  504.  
  505.    /* Is this a non-CM event? */
  506.    if (newnodelist && (e_ptrs[cur_event]->behavior & MAT_NOCM) &&
  507.       (newnodedes.NodeFlags & B_CM))
  508.       {
  509.       return (rettype);
  510.       }
  511.  
  512.    /* See if we spent too much calling him already */
  513.    if (bad_call (p1->zone, p1->net, p1->node, 0))
  514.       {
  515.       p1->mailtypes |= MAIL_TOOBAD;
  516.       return (rettype);
  517.       }
  518.  
  519.    p1->mailtypes |= MAIL_WILLGO;
  520.  
  521.    return (rettype);
  522. }
  523.  
  524. static char mail_stat (p)
  525. MAILP p;
  526. {
  527.    if (p->mailtypes & MAIL_UNKNOWN)
  528.       return ('!');
  529.    if (p->mailtypes & MAIL_TOOBAD)
  530.       return ('x');
  531.    if (p->mailtypes & MAIL_TRIED)
  532.       return ('#');
  533.    if (p->mailtypes & MAIL_WILLGO)
  534.       return ('*');
  535.    return ('-');
  536. }
  537.  
  538. void xmit_window (p1)
  539. MAILP p1;
  540. {
  541.    MAILP p;
  542.    int i;
  543.    char j[40];
  544.    char j1[40];
  545.  
  546.    if (!fullscreen)
  547.       return;
  548.  
  549.    p = p1;
  550.  
  551.    sb_fillc (holdwin, ' ');
  552.  
  553.    if (p == NULL)
  554.       {
  555.       sb_move (holdwin, 3, 5);
  556.       sb_puts (holdwin, "Nothing in Outbound Area");
  557.       return;
  558.       }
  559.  
  560.    sb_move (holdwin, 1, 2);
  561.    sb_puts (holdwin, "Node              C H D N R S");
  562.  
  563.    for (i = 2; i < 6; i++)
  564.       {
  565.       if (p == NULL)
  566.          break;
  567.  
  568.       sb_move (holdwin, i, 2);
  569.       sprintf (j, "%d:%d/%d", p->zone, p->net, p->node);
  570.       sprintf (j1, "%-17.17s %c %c %c %c %c %c", j,
  571.          (p->mailtypes & MAIL_CRASH  ) ? '*' : ' ',
  572.          (p->mailtypes & MAIL_HOLD     ) ? '*' : ' ',
  573.          (p->mailtypes & MAIL_DIRECT ) ? '*' : ' ',
  574.          (p->mailtypes & MAIL_NORMAL ) ? '*' : ' ',
  575.          (p->mailtypes & MAIL_REQUEST) ? '*' : ' ',
  576.          mail_stat (p));
  577.       sb_puts (holdwin, j1);
  578.       p = p->next;
  579.       }
  580.  
  581.    p = mail_top;
  582.  
  583.    for (; i < 6; i++)
  584.       {
  585.       if ((p == p1) || (p == NULL))
  586.          break;
  587.  
  588.       sb_move (holdwin, i, 2);
  589.       sprintf (j, "%d:%d/%d", p->zone, p->net, p->node);
  590.       sprintf (j1, "%-17.17s %c %c %c %c %c %c", j,
  591.          (p->mailtypes & MAIL_CRASH  ) ? '*' : ' ',
  592.          (p->mailtypes & MAIL_HOLD     ) ? '*' : ' ',
  593.          (p->mailtypes & MAIL_DIRECT ) ? '*' : ' ',
  594.          (p->mailtypes & MAIL_NORMAL ) ? '*' : ' ',
  595.          (p->mailtypes & MAIL_REQUEST) ? '*' : ' ',
  596.          mail_stat (p));
  597.       sb_puts (holdwin, j1);
  598.       p = p->next;
  599.       }
  600.  
  601.    sb_show ();
  602. }
  603.  
  604. static void xmit_sort ()
  605. {
  606.    MAILP p, p1, p2;
  607.  
  608.    p = mail_top;
  609.  
  610.    /* Find the first that is sendable */
  611.    while (p != NULL)
  612.       {
  613.       if ((p->mailtypes & MAIL_WILLGO) &&
  614.          (!(p->mailtypes & MAIL_TOOBAD)) &&
  615.          (!(p->mailtypes & MAIL_UNKNOWN)))
  616.          break;
  617.       p = p->next;
  618.       }
  619.  
  620.    if (p == NULL)
  621.       return;
  622.  
  623.    /* Put the first sendable one on top */
  624.    if (p != mail_top)
  625.       {
  626.       p->prev->next = p->next;
  627.       if (p->next != NULL)
  628.          p->next->prev = p->prev;
  629.       p->prev = NULL;
  630.       p->next = mail_top;
  631.       mail_top->prev = p;
  632.       mail_top = p;
  633.       }
  634.  
  635.    p1 = p;
  636.    p = p1->next;
  637.    while (p != NULL)
  638.       {
  639.       if ((p->mailtypes & MAIL_WILLGO) &&
  640.          (!(p->mailtypes & MAIL_TOOBAD)) &&
  641.          (!(p->mailtypes & MAIL_UNKNOWN)))
  642.          {
  643.          if (p->prev == p1)
  644.             {
  645.             p1 = p;
  646.             p = p->next;
  647.             continue;
  648.             }
  649.          p2 = p->next;
  650.          p->prev->next = p->next;
  651.          if (p->next != NULL)
  652.             p->next->prev = p->prev;
  653.          p->next = p1->next;
  654.          if (p1->next != NULL)
  655.             p1->next->prev = p;
  656.          p->prev = p1;
  657.          p1->next = p;
  658.          p1 = p;
  659.          p = p2;
  660.          }
  661.       else
  662.          {
  663.          p = p->next;
  664.          }
  665.       }
  666. }
  667.  
  668. void xmit_reset ()
  669. {
  670.    MAILP p;
  671.    int i, j, done, zone;
  672.  
  673.    /* First get rid of all the old junk */
  674.    p = mail_top;
  675.    if (p != NULL)
  676.       {
  677.       while (p->next != NULL)
  678.          p = p->next;
  679.       while (p->prev != NULL)
  680.          {
  681.          p = p->prev;
  682.          free (p->next);
  683.          }
  684.       if (p != NULL)
  685.          free (p);
  686.       }
  687.  
  688.    p = mail_top = NULL;
  689.  
  690.    zone = alias[0].Zone;
  691.  
  692.    if( !str_dh ) str_dh = opendir();  /*PLF Sat  05-06-1989  01:35:26 */
  693.  
  694.    while (zone > 0)
  695.       {
  696.       i = 0;
  697.       while (outb[i] != NULL)
  698.          {
  699.          sprintf (next_one, "%s%s", HoldAreaNameMunge(zone), outb[i++]);
  700.  
  701.          done = 0;
  702.          j = 0;
  703.          while (!done)
  704.             {
  705.             /* See if we have any more at this level */
  706. /*PLF        if (dfind (&dta_str, next_one, j)) */
  707.             if ( (j) ? findnext(str_dh) : findfirst(next_one, _A_NORMAL, str_dh) ) /*PLF this is ugly but preserves the old logic */
  708.                {
  709.                /* No more at this level, so go to next level */
  710.                done = 1;
  711.                }
  712.             else
  713.                {
  714.                /* We found a name, remember it */
  715.                if (p == NULL)
  716.                   {
  717.                   p = mail_top = (MAILP) calloc (sizeof (MAIL), 1);
  718.                   }
  719.                else
  720.                   {
  721.                   p->next = (MAILP) calloc (sizeof (MAIL), 1);
  722.                   p->next->prev = p;
  723.                   p = p->next;
  724.                   }
  725.  
  726.                if (xmit_install (p, zone, str_dh->name))
  727.                   {
  728.                   /* No good */
  729.                   if (p->prev != NULL)
  730.                      {
  731.                      p = p->prev;
  732.                      free (p->next);
  733.                      p->next = NULL;
  734.                      }
  735.                   else
  736.                      {
  737.                      free (p);
  738.                      p = mail_top = NULL;
  739.                      }
  740.                   }
  741.  
  742.                ++j;
  743.                }
  744.             }
  745.          }
  746.  
  747.       if (no_zones)
  748.          break;
  749.  
  750.       /* Get the next zone number */
  751.       zone = nodefind (-1, 0, 0, 0);
  752.       if (zone == alias[0].Zone)
  753.          zone = nodefind (-1, 0, 0, 0);
  754.       }
  755.  
  756.    next_mail = NULL;
  757.  
  758.    xmit_sort ();
  759.  
  760.    xmit_window (mail_top);
  761. }
  762.  
  763. int xmit_next (zone, net, node)
  764. int *zone, *net, *node;
  765. {
  766.    /* Set up the proper pointer */
  767.    if ((next_mail == NULL) || (next_mail->next == NULL))
  768.       {
  769.       next_mail = mail_top;
  770.       }
  771.    else
  772.       {
  773.       next_mail = next_mail->next;
  774.       }
  775.  
  776.    /* Loop through till we find something we can send */
  777.    while (next_mail != NULL)
  778.       {
  779.       if ((next_mail->mailtypes & MAIL_WILLGO) &&
  780.           (!(next_mail->mailtypes & MAIL_UNKNOWN)) &&
  781.           (!(next_mail->mailtypes & MAIL_TOOBAD)))
  782.          {
  783.          if (bad_call (next_mail->zone, next_mail->net, next_mail->node, 0))
  784.             {
  785.             next_mail->mailtypes |= MAIL_TOOBAD;
  786.             }
  787.          else
  788.             {
  789.             *zone = next_mail->zone;
  790.             *net = next_mail->net;
  791.             *node = next_mail->node;
  792.             xmit_window (next_mail);
  793.             return (1);
  794.             }
  795.          }
  796.       next_mail = next_mail->next;
  797.       }
  798.  
  799.    /* Read the disk again since we reached the end of the list */
  800. /* I commented this out because I think it is better just to do it
  801.    every 10 minutes */
  802. /*     xmit_reset (); */
  803.  
  804.    next_mail = mail_top;
  805.  
  806.    /* Try the new list and see what happens */
  807.    while (next_mail != NULL)
  808.       {
  809.       if ((next_mail->mailtypes & MAIL_WILLGO) &&
  810.           (!(next_mail->mailtypes & MAIL_UNKNOWN)) &&
  811.           (!(next_mail->mailtypes & MAIL_TOOBAD)))
  812.          {
  813.          if (bad_call (next_mail->zone, next_mail->net, next_mail->node, 0))
  814.             {
  815.             next_mail->mailtypes |= MAIL_TOOBAD;
  816.             }
  817.          else
  818.             {
  819.             *zone = next_mail->zone;
  820.             *net = next_mail->net;
  821.             *node = next_mail->node;
  822.             xmit_window (next_mail);
  823.             return (1);
  824.             }
  825.          }
  826.       next_mail = next_mail->next;
  827.       }
  828.  
  829.    /* Oh well, we tried */
  830.    xmit_window (mail_top);
  831.    return (0);
  832. }
  833.  
  834. void xmit_delete ()
  835. {
  836.    MAILP p;
  837.    int i;
  838.  
  839.    if (next_mail == NULL)
  840.       return;
  841.    if(!str_dh) str_dh = opendir();    /*PLF Sat  05-06-1989  01:47:35 */
  842.    i = 0;
  843.    while (outb[i] != NULL)
  844.       {
  845.       sprintf (next_one, "%s%04x%04x.%s",
  846.                HoldAreaNameMunge(next_mail->zone),
  847.                next_mail->net, next_mail->node, &(outb[i++][2]));
  848.  
  849.       if (!findfirst(next_one, _A_NORMAL, str_dh))
  850.          {
  851.          status_line ("!Still have mail for %d:%d/%d",
  852.             next_mail->zone, next_mail->net, next_mail->node);
  853.          /* We still have something for him */
  854.          next_mail->mailtypes &= ~MAIL_WILLGO;
  855.          next_mail->mailtypes |= MAIL_TRIED;
  856.          return;
  857.          }
  858.       }
  859.  
  860.    if (next_mail != mail_top)
  861.       {
  862.       p = next_mail->next;
  863.       next_mail = next_mail->prev;
  864.       free (next_mail->next);
  865.       next_mail->next = p;
  866.       if (p != NULL)
  867.          p->prev = next_mail;
  868.       xmit_window (next_mail);
  869.       }
  870.    else
  871.       {
  872.       mail_top = mail_top->next;
  873.       free (next_mail);
  874.       if (mail_top != NULL)
  875.          mail_top->prev = NULL;
  876.       xmit_window (mail_top);
  877.       next_mail = NULL;
  878.       }
  879.  
  880. }
  881.  
  882. void receive_exit ()
  883. {
  884.    char junk1[150];
  885.  
  886.    if (got_arcmail && (cur_event >= 0) && (e_ptrs[cur_event]->errlevel[2]))
  887.       {
  888.       status_line (":Exit after compressed mail with errorlevel %d",
  889.                    e_ptrs[cur_event]->errlevel[2]);
  890.  
  891.       errl_exit (e_ptrs[cur_event]->errlevel[2]);
  892.       }
  893.  
  894.    if ((got_mail || got_packet) &&
  895.        (cur_event >= 0) && (e_ptrs[cur_event]->errlevel[1]))
  896.       {
  897.       status_line (":Exit after receiving mail with errorlevel %d",
  898.                    e_ptrs[cur_event]->errlevel[1]);
  899.  
  900.       errl_exit (e_ptrs[cur_event]->errlevel[1]);
  901.       }
  902.  
  903.    if ((aftermail != NULL) && (got_mail || got_packet || got_arcmail))
  904.       {
  905.       status_line (":Received mail, running 'AfterMail' program");
  906.       mdm_init (modem_busy);
  907.       DTR_OFF ();
  908.       scr_printf ("\033[H\033[2J");
  909.       vfossil_cursor (1);
  910.       strcpy (junk1, aftermail);
  911.       if (cur_event >= 0)
  912.          strcat (junk1, e_ptrs[cur_event]->cmd);
  913.       close_up ();
  914.       b_spawn (junk1);
  915.       come_back ();
  916.       DTR_ON ();
  917.       status_line ("#Re-enabling system following 'AfterMail' program");
  918.       mdm_init (modem_init);
  919.       xmit_reset ();
  920.       }
  921.  
  922.    got_arcmail = 0;
  923.    got_packet = 0;
  924.    got_mail = 0;
  925. }
  926.  
  927. void errl_exit (n)
  928. int n;
  929. {
  930.    write_sched ();
  931.  
  932.    status_line ("+end, %s", xfer_id);
  933.    mdm_init (modem_busy);                         /* Reinitialize the modem    */
  934.    DTR_OFF ();                                     /* Drop DTR to avoid calls */
  935.     /*SCB*/ if (fullscreen)
  936.       gotoxy (0, 23);
  937.  
  938.    if (vfossil_installed)
  939.       vfossil_close ();
  940.  
  941.    if (!share)
  942.       MDM_DISABLE ();
  943.    exit (n);
  944. }
  945.  
  946. long random_time (x)
  947. int x;
  948. {
  949.    int i;
  950.    long timerset ();
  951.  
  952.    if (x == 0)
  953.       {
  954.       return (0L);
  955.       }
  956.  
  957.    /* Number of seconds to delay is random based on x +/- 50% */
  958.    i = (rand () % (x + 1)) + (x / 2);
  959.  
  960.    return (timerset (i * 100));
  961. }
  962.  
  963.  
  964. char *HoldAreaNameMunge(bzone)
  965. int bzone;
  966. {
  967.    static char munged[80];
  968.    register char *p, *q;
  969.  
  970.    p = hold_area;
  971.    if ((bzone == alias[0].Zone) || (no_zones))
  972.       return(p);
  973.    q = munged;
  974.    while (*p)
  975.       *q++ = *p++;
  976.    --q;
  977.    sprintf(q,".%03x\\",bzone);
  978.    return(munged);
  979. }
  980.  
  981.  
  982. static char fname[80];
  983. static char fname1[80];
  984.  
  985. int bad_call (bzone, bnet, bnode, rwd)
  986. int bzone;
  987. int bnet;
  988. int bnode;
  989. int rwd;
  990. {
  991.    int res;
  992.    int i, j;
  993.    FSCAN *bad_dh;  /*PLF Fri  05-05-1989  23:36:38 */
  994.    FILE *bad_wazoo;
  995.    char *p;
  996.    char *HoldName;
  997.  
  998.    HoldName = HoldAreaNameMunge(bzone);
  999.    sprintf (fname, "%s%04x%04x.$$?", HoldName, bnet, bnode);
  1000.    j = strlen (fname) - 1;                         /* Point at ?            */
  1001.    res = -1;                                     /* Initialize to fail    */
  1002.    bad_dh = opendir(); /*PLF Fri  05-05-1989  23:37:13 */
  1003.    i = 0;                                         /* This says findfirst */
  1004.                                                 /* as long as we match */
  1005. /*PLF    while (!dfind (&bad_dh, fname, i))       */
  1006.    while (!( (i) ? findnext(bad_dh) : findfirst(fname, _A_NORMAL, bad_dh) ))  /*PLF Fri  05-05-1989  23:45:28 */
  1007.       {
  1008.       if (isdigit (bad_dh->name[11]))             /* is there a digit?    */
  1009.          {
  1010.          fname[j] = bad_dh->name[11];             /* Yes, copy to fname    */
  1011.          res = fname[j] - '0';                   /* Save it for testing */
  1012.          break;                                  /* Get out of while    */
  1013.          }
  1014.       else i = 1;                                 /* Else use findnext    */
  1015.       }
  1016.    closedir(bad_dh);   /*PLF Fri  05-05-1989  23:47:06 */
  1017.    if (res == -1)                                 /* Successful search?    */
  1018.       {
  1019.       fname[j] = '0';                            /* No, base digit = 0  */
  1020.       }
  1021.  
  1022.    if (rwd > 0)
  1023.       {
  1024.       /* Writing a bad call  */
  1025.  
  1026.       /* First create a filename that is one higher than what we've got */
  1027.       strcpy (fname1, fname);
  1028.       fname1[j]++;
  1029.       if (fname1[j] > '9')
  1030.          fname1[j] = '9';
  1031.  
  1032.       if (res == -1)                             /* Did we have a file? */
  1033.          {                                         /* No, make one.        */
  1034.          if (rwd == 2)                             /* No carrier */
  1035.             res = open (fname, O_CREAT + O_WRONLY + O_BINARY, S_IWRITE);
  1036.          else /* With carrier */ res = open (fname1, O_CREAT + O_WRONLY + O_BINARY, S_IWRITE);
  1037.          i = rwd - 1;                             /* zero-based count    */
  1038.          write (res, (char *) &i, sizeof (int)); /* write it out        */
  1039.          close (res);                             /* close the file        */
  1040.          }
  1041.       else
  1042.          {                                         /* There was a file    */
  1043.  
  1044.          /*
  1045.           * 2 = Unsuccessful, No carrier. Update contents of the file.
  1046.           */
  1047.  
  1048.          if (rwd == 2)
  1049.             {
  1050.             i = open (fname, O_RDONLY + O_BINARY);
  1051.             read (i, (char *) &res, sizeof (int));
  1052.             close (i);
  1053.  
  1054.             ++res;
  1055.  
  1056.             i = open (fname, O_CREAT + O_WRONLY + O_BINARY, S_IWRITE);
  1057.             write (i, (char *) &res, sizeof (int));
  1058.             close (i);
  1059.             }
  1060.  
  1061.          /*
  1062.           * 1 = Unsuccessful, Carrier. Update file name to reflect the
  1063.           * failure.
  1064.           */
  1065.  
  1066.          else
  1067.             {
  1068.             rename (fname, fname1);
  1069.             }
  1070.          }
  1071.       }
  1072.    else if (rwd == 0)
  1073.       {
  1074.  
  1075.       /*
  1076.        * 0 = We are reading a bad call status
  1077.        */
  1078.  
  1079.       /* Is it automatically ok (no .$$ file there) ? */
  1080.       if (res == -1)
  1081.          return (0);
  1082.  
  1083.       /* Were there too many connects with carrier? */
  1084.       if (res >= max_connects)
  1085.          return (1);
  1086.  
  1087.       /* Ok, check for connects without carrier */
  1088.       res = 0;
  1089.       i = open (fname, O_RDONLY + O_BINARY);
  1090.       read (i, (char *) &res, sizeof (int));
  1091.       close (i);
  1092.       return (res >= max_noconnects);
  1093.       }
  1094.    else
  1095.       {
  1096.  
  1097.       /*
  1098.        * -1 = Cleanup of bad call status. This happens in two steps:    a)
  1099.        * delete 'netnode.$$?' in hold area; b) if a 'netnode.Z' file exists in
  1100.        * hold area, 1) delete all BADWAZOO.xxx files listed in the .Z file; 2)
  1101.        * delete the 'netnode.z' file.
  1102.        */
  1103.  
  1104.       if (res != -1)
  1105.          {
  1106.          unlink (fname);
  1107.          }
  1108.  
  1109.       if (!mail_finished)
  1110.          return (0);
  1111.  
  1112.       sprintf (fname, "%s%04x%04x.Z", HoldName, bnet, bnode);
  1113.       if (dexists (fname))
  1114.          {
  1115.          errno = 0;
  1116.          bad_wazoo = fopen (fname, read_ascii);
  1117.          if (!got_error (OPEN_msg, fname))
  1118.             {
  1119.             while (!feof (bad_wazoo))
  1120.                {
  1121.                e_input[0] = '\0';
  1122.                if (!fgets (e_input, 64, bad_wazoo))
  1123.                   break;
  1124.                /* Point to BADWAZOO.xxx */
  1125.                p = strchr (e_input, ' ') + 1;
  1126.                /* Then just past it and terminate */
  1127.                p = strchr (p, ' ');
  1128.                *p = '\0';
  1129.                /* Back to where we were */
  1130.                p = strchr (e_input, ' ') + 1;
  1131.  
  1132.                /* Build file name and delete file */
  1133.                strcpy (fname1, CurrentNetFiles);
  1134.                strcat (fname1, p);
  1135.                unlink (fname1);
  1136.                }
  1137.             fclose (bad_wazoo);
  1138.             }
  1139.          unlink (fname);
  1140.          }
  1141.       }
  1142.    return (0);
  1143. }
  1144.  
  1145. void mailer_banner ()
  1146. {
  1147.    if (fullscreen && un_attended)
  1148.       {
  1149.       vfossil_cursor (0);
  1150.       sb_move (settingswin, SET_EVNT_ROW, SET_COL);
  1151.       sprintf (junk, "%-2d", cur_event + 1);
  1152.       sb_puts (settingswin, junk);
  1153.       sprintf (junk, "%-5u Com%d", cur_baud, port_ptr + 1);
  1154.       sb_move (settingswin, SET_PORT_ROW, SET_COL);
  1155.       sb_puts (settingswin, junk);
  1156.       clear_filetransfer ();
  1157.       }
  1158.  
  1159.    set_baud (max_baud, 0);
  1160. }
  1161.  
  1162. void clear_filetransfer ()
  1163. {
  1164.    if (fullscreen)
  1165.       sb_fillc (filewin, ' ');
  1166. }
  1167.  
  1168. static char ebuf[10];
  1169. static char *estring (e)
  1170. int e;
  1171. {
  1172.    ebuf[0] = '\0';
  1173.    if (e >= 0)
  1174.       {
  1175.       if (e_ptrs[e]->behavior & MAT_BBS)
  1176.          strcat (ebuf, "B");
  1177.       if (e_ptrs[e]->behavior & MAT_CM)
  1178.          strcat (ebuf, "C");
  1179.       if (e_ptrs[e]->behavior & MAT_DYNAM)
  1180.          strcat (ebuf, "D");
  1181.       if (e_ptrs[e]->behavior & MAT_NOCM)
  1182.          strcat (ebuf, "K");
  1183.       if (e_ptrs[e]->behavior & MAT_LOCAL)
  1184.          strcat (ebuf, "L");
  1185.       if (e_ptrs[e]->behavior & MAT_NOREQ)
  1186.          strcat (ebuf, "N");
  1187.       if (e_ptrs[e]->behavior & MAT_OUTONLY)
  1188.          strcat (ebuf, "S");
  1189.       if (e_ptrs[e]->behavior & MAT_NOOUT)
  1190.          strcat (ebuf, "R");
  1191.       }
  1192.    return (ebuf);
  1193. }
  1194.  
  1195. void do_ready (str)
  1196. char *str;
  1197. {
  1198.    if (fullscreen)
  1199.       {
  1200.       if (!doing_poll)
  1201.          {
  1202.          clear_filetransfer ();
  1203.          }
  1204.  
  1205.       sb_move (settingswin, SET_EVNT_ROW, SET_COL);
  1206.       sprintf (junk, "%-2d/%-6.6s", cur_event + 1, estring (cur_event));
  1207.       sb_puts (settingswin, junk);
  1208.       sb_move (settingswin, SET_STAT_ROW, SET_COL);
  1209.       sb_puts (settingswin, str);
  1210.       sb_show ();
  1211.       }
  1212. }
  1213.